      // 1.获取学员信息
      // 渲染到页面上
      async function render() {
        const res = await axios({ url: "/students" });
        console.log("res:", res);
        const html = res.data
          .map(
            v => `  <tr>
                      <td>${v.name}</td>
                      <td>${v.age}</td>
                      <td>${v.gender === 0 ? "男" : "女"}</td>
                      <td>第${v.group}组</td>
                      <td>${v.hope_salary}</td>
                      <td>${v.salary}</td>
                      <td>${v.province + v.city + v.area}</td>
                      <td>
                        <a href="javascript:;" class="text-success mr-3"><i class="bi bi-pen" data-id="${
                          v.id
                        }"></i></a>
                        <a href="javascript:;" class="text-danger"><i class="bi bi-trash" data-id="${
                          v.id
                        }"></i></a>
                      </td>
                    </tr>`
          )
          .join("");
        document.querySelector(".list").innerHTML = html;
        document.querySelector(".total").innerHTML = res.data.length;
      }
      render();
      // 2.事件委托删除
      document.querySelector("tbody").onclick = async function (e) {
        if (e.target.classList.contains("bi-trash")) {
          const res = await axios({
            url: `/students/${e.target.dataset.id}`,
            method: "delete",
          });
          console.log("res:", res);
          // 接口能正常调用，直接重新渲染即可
          render();
        }
      };
      // 3.弹框部分
      // 3-1.获取弹框
      const modal = new bootstrap.Modal(document.querySelector("#modal"));
      // 2.点击新增弹框
      document
        .querySelector("#openModal")
        .addEventListener("click", function () {
          document.querySelector("#form").reset();
          // 修改标题
          document.querySelector(".modal-title").innerHTML = "添加学员";
          // 存add的自定义属性到确认按钮上
          document.querySelector("#submit").dataset.id = "add";
          modal.show();
        });
      // 3.点击编辑弹框
      document
        .querySelector(".list")
        .addEventListener("click", async function (e) {
          // 点击的是编辑
          if (e.target.classList.contains("bi-pen")) {
            // 修改标题
            document.querySelector(".modal-title").innerHTML = "修改学员";
            // 具体id存到确认按钮上
            document.querySelector("#submit").dataset.id = e.target.dataset.id;

            // 获取学院信息
            const res = await axios({
              url: `/students/${e.target.dataset.id}`,
            });
            console.log("res:", res);
            // 渲染到弹框中
            // 个别数据需要特殊处理
            // document.querySelector("[name=name]").value = res.data.name;
            // document.querySelector("[name=age]").value = res.data.age;
            // document.querySelector("[name=group]").value = res.data.group;
            // document.querySelector("[name=hope_salary]").value =
            //   res.data.hope_salary;
            // document.querySelector("[name=salary]").value = res.data.salary;
            // // 性别选项要用 checked 属性才能选中
            // const genderSel = document.querySelectorAll("[name=gender]");
            // genderSel[res.data.gender].checked = true;
            // 性别特殊设置

            // 简化的写法
            for (const key in res.data) {
              // 有一些key 对应到 `[name=xxx]`属性选择器找不到元素
              // console.log('key:', key)
              // 性别特殊设置
              if (key === "gender") {
                // 性别 设置checked属性
                const genderChks = document.querySelectorAll("[name=gender]");
                genderChks[res.data[key]].checked = true;
              } else {
                // 循环挨个的赋值 不是性别设置value即可
                const ipt = document.querySelector(`[name=${key}]`);
                // 考虑 ipt不存在的情况
                ipt && (ipt.value = res.data[key]);
              }
            }

            // 省市区 需要重新获取并渲染
            await renderProvince(res.data.province);
            await renderCity(res.data.city);
            await renderArea(res.data.area);
            // 弹框
            modal.show();
          }
        });
      // 4.提交数据
      document
        .querySelector("#submit")
        .addEventListener("click", async function () {
          async function fn(method, id = "") {
            const data = serialize(document.querySelector("#form"), {
              hash: true,
            });
            ["age", "gender", "salary", "hope_salary", "group"].forEach(k => {
              data[k] = +data[k];
            });
           const res = await axios({
              url: `/students/${id}`,
              method: method,
              data,
           });
            console.log('res:',res);
            // 关闭弹框
            modal.hide();
            // 重置表单
            document.querySelector("#form").reset();
            // 省市区 重新获取一次
            await renderSelect();
            // 更新页面
            render();
            tip(res.message)
          }
          if (this.dataset.id === "add") {
            fn("post");
          } else {
            fn("put", this.dataset.id);
          }
        });
      //5.省市区数据获取
      // 获取省数据
      const provinceSel = document.querySelector('[name="province"]');
      const citySel = document.querySelector('[name="city"]');
      const areaSel = document.querySelector('[name="area"]');
      async function renderProvince(province) {
        // 省
        const res = await axios({
          url: "/api/province",
        });
        provinceSel.innerHTML = res.data
          .map(v => `<option value="${v}">${v}</option>`)
          .join("");
        // 如果传参 就设置select的value
        province && (provinceSel.value = province);
      }
      // 获取市数据
      async function renderCity(city) {
        // 市
        const res = await axios({
          url: "/api/city",
          params: {
            pname: provinceSel.value,
          },
        });
        citySel.innerHTML = res.data
          .map(v => `<option value="${v}">${v}</option>`)
          .join("");
        // 如果传参 就设置select的value
        city && (citySel.value = city);
      }
      // 获取区数据
      async function renderArea(area) {
        // 区
        const res = await axios({
          url: "/api/area",
          params: {
            pname: provinceSel.value,
            cname: citySel.value,
          },
        });
        areaSel.innerHTML = res.data
          .map(v => `<option value="${v}">${v}</option>`)
          .join("");
        // 如果传参 就设置select的value
        area && (areaSel.value = area);
      }
      // 省市区
      async function renderSelect() {
        await renderProvince();
        await renderCity();
        await renderArea();
      }
      renderSelect();
      // 省市区联动
      provinceSel.onchange = async function () {
        await renderCity();
        await renderArea();
      };
      citySel.onchange = async function () {
        await renderArea();
      };